	package com.pattern.command.undocalc;

	import java.util.Arrays;
	import java.util.List;
	import net.mindview.util.Stack;

	public class UndoCalc {
		int result;
		OperatorFactory operatorFactory = new UndoOperatorFactory();

		public String calc(String... cmd) {
			try {
				result = Integer.valueOf(cmd[0]);
				for (int i = 1; i < cmd.length; ++i) {
					String c = cmd[i];
					if (isOperator(c)) {
						Operator op = getNewOperator(c);
						String nextC = cmd[++i];
						result = op.calc(result, Integer.valueOf(nextC));
						pushOp((Undoable) op);
					} else if (isUndo(c)) {
						Undoable op = popOp();
						result = op.undo();
					}
				}
				return String.valueOf(result);
			} catch (Exception e) {
				return "ERROR INPUT";
			}
		}

		private Stack<Undoable> opStack = new Stack<Undoable>();

		private Undoable popOp() {
			return opStack.pop();
		}

		/*
		 * (non-javadoc)
		 */
		private Operator operator;

		private void pushOp(Undoable op) {
			opStack.push(op);
		}

		private boolean isUndo(String c) {
			return "<".equals(c);
		}

		private Operator getNewOperator(String c) {
			return operatorFactory.getOperator(c);
		}

		private static String[] ops = new String[] { "+", "-", "*", "/" };
		private static List<String> opList = Arrays.asList(ops);

		private boolean isOperator(String c) {
			return opList.contains(c);
		}

		/**
		 * Getter of the property <tt>operator</tt>
		 * 
		 * @return Returns the operator.
		 * 
		 */

		public Operator getOperator() {
			return operator;
		}

		/**
		 * Setter of the property <tt>operator</tt>
		 * 
		 * @param operator
		 *            The operator to set.
		 * 
		 */
		public void setOperator(Operator operator) {
			this.operator = operator;
		}
	}
